type ParamsAndPath = {
  params?: {
    [key: string]: number | string | object | boolean | (number | string | object | boolean)[]
  }
  pathData?: (number | string)[]
  instanceName?: string
}

//!拓展option的类型，可以加上params和pathData字段
type RequestOption = WechatMiniprogram.RequestOption & ParamsAndPath

//接收类型参数，为服务器响应数据的类型
export function request<T>(this: any, option: RequestOption, isLogin?: boolean): Promise<T> {
  //处理params和path参数，并解析到url中
  const paramsKeys = option.params && Object.keys(option.params)

  let parsedUrl = option.url

  if (option.pathData && option.pathData.length > 0) {
    option.pathData.forEach(item => (parsedUrl += `/${item.toString()}`))
  }

  if (paramsKeys && paramsKeys.length > 0) {
    paramsKeys.forEach((key, index) => {
      parsedUrl += `${index === 0 ? "?" : "&"}${key}=${
        typeof option.params![key] === "string" ? option.params![key] : JSON.stringify(option.params![key])
      }`
    })
  }

  return new Promise((resolve, reject) => {
    const reqInstance = wx.request({
      ...option,
      header: {
        cookie: wx.getStorageSync("cookie"),
      },
      url: "http://localhost:3000" + parsedUrl,

      success(res: WechatMiniprogram.RequestSuccessCallbackResult<T>) {
        if (isLogin) {
          //只有登录接口中服务器给的cookies中的"MUSIC_U"开头的字段cookie是有用的
          const cookie = res.cookies.find(item => item.startsWith("MUSIC_U"))
          cookie && wx.setStorage({ key: "cookie", data: cookie })
        }

        resolve(res.data)
      },
      fail(err) {
        reject(err)
      },
    })
    if (this) {
      this.abort = reqInstance.abort.bind(reqInstance)
    }
  })
}
